package com.example.ww.bleapp.activity;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleGattCallback;
import com.clj.fastble.callback.BleIndicateCallback;
import com.clj.fastble.callback.BleMtuChangedCallback;
import com.clj.fastble.callback.BleNotifyCallback;
import com.clj.fastble.callback.BleReadCallback;
import com.clj.fastble.callback.BleRssiCallback;
import com.clj.fastble.callback.BleScanCallback;
import com.clj.fastble.callback.BleWriteCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.clj.fastble.scan.BleScanRuleConfig;
import com.example.ww.bleapp.R;
import com.example.ww.bleapp.adapter.BlutoothListAdapter;
import com.example.ww.bleapp.utils.BaseActivity;
import com.example.ww.bleapp.utils.PermissionListener;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MainActivity extends BaseActivity implements View.OnClickListener {

    /**
     * 蓝牙BLE开发运用到FastBle
     */
    private Button mConnect;
    private RecyclerView mRecyclerview;
    private Context context;
    private List<BleDevice> bleDeviceList = new ArrayList<>();
    private BlutoothListAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;
        initView();
    }

    private void initView() {
        mConnect = (Button) findViewById(R.id.connect);
        mConnect.setOnClickListener(this);
        mRecyclerview = (RecyclerView) findViewById(R.id.recyclerview);

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
        mRecyclerview.setLayoutManager(linearLayoutManager);
        adapter = new BlutoothListAdapter(context, bleDeviceList);
        mRecyclerview.setAdapter(adapter);

        permission();//动态权限申请
        initBLE();//蓝牙BLE的配置
    }

    private void initBLE() {
        BleManager.getInstance().init(getApplication());
        BleManager.getInstance()
                .enableLog(true)
                .setReConnectCount(1, 5000)
                .setOperateTimeout(5000);
        //判断当前设备是否支持BLE
//        BleManager.getInstance().isSupportBle();
//        //判断当前设备蓝牙是否打开
//        BleManager.getInstance().isBlueEnable();
//        //通过蓝牙适配器直接打开蓝牙
//        BleManager.getInstance().enableBluetooth();
//        //通过startactivityforResult引导页面引导用户打开蓝牙
//        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//        startActivityForResult(intent, 0x01);

        /**
         * 扫描钱的规则制定
         */
        BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder()
//                .setServiceUuids(serviceUuids)//只扫描自定的服务设备
//        .setDeviceName(true,names)//只扫描制定广播名的设备
//        .setDeviceMac(mac)//只扫描制定mac的设备
//        .setAutoConnect(isAutoConnect)//是否自动连接，默认false
                .setScanTimeOut(10000)//扫描超时时间，单位为s,默认为10s
                .build();
        BleManager.getInstance().initScanRule(scanRuleConfig);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            default:
                break;
            case R.id.connect:
                if (BleManager.getInstance().isSupportBle()) {
                    if (BleManager.getInstance().isBlueEnable()) {
                        /**
                         * 开始扫描
                         */
                        BleManager.getInstance().scan(new BleScanCallback() {
                            @Override
                            public void onScanFinished(List<BleDevice> scanResultList) {
                                //本次扫描时段内所有被扫描且过滤后的设备集合，回到主线程，相当于onScanning设置之和
                            }

                            @Override
                            public void onScanStarted(boolean success) {
                            }

                            @Override
                            public void onScanning(BleDevice bleDevice) {
                                //扫描过程总的所有过滤后的结果回调，它会回到主线程，同一个设备只会出现一次，出现的设备是经过扫描规则过滤后的设备
                                bleDeviceList.add(bleDevice);
                                adapter.notifyDataSetChanged();
                            }

                            @Override
                            public void onLeScan(BleDevice bleDevice) {
                                super.onLeScan(bleDevice);
                            }
                        });

                        adapter.setOnItemClickListener(new BlutoothListAdapter.OnItemClickListener() {
                            @Override
                            public void onClick(int position) {
                                /**
                                 * 连接，断链，监控连接状态
                                 */
                                Toast.makeText(context, bleDeviceList.get(position).getName(), Toast.LENGTH_SHORT).show();
                                BleManager.getInstance().connect(bleDeviceList.get(position), new BleGattCallback() {
                                    @Override
                                    public void onStartConnect() {
                                        //开始进行连接
                                    }

                                    @Override
                                    public void onConnectFail(BleDevice bleDevice, BleException exception) {
                                        //连接不成功
                                        Toast.makeText(MainActivity.this, "蓝牙连接不成功", Toast.LENGTH_SHORT).show();
                                    }

                                    @Override
                                    public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
                                        //连接成功并发现服务
//                                        BluetoothGatt gatt = BleManager.getInstance().getBluetoothGatt(bleDevice);
                                        List<BluetoothGattService> serviceList = gatt.getServices();
                                        for (BluetoothGattService service : serviceList) {
                                            UUID uuid_service = service.getUuid();
                                            Log.e("uuid_service", uuid_service + "");
                                            List<BluetoothGattCharacteristic> characteristicList = service.getCharacteristics();
                                            for (BluetoothGattCharacteristic characteristic : characteristicList) {
                                                UUID uuid_chara = characteristic.getUuid();
//                                                Log.e("uuid_chara", uuid_chara + "");
                                            }
                                        }


                                        String uuid_service = "", uuid_characteristic_notify = "", uuid_characteristic_indicate = "",
                                                uuid_characteristic_read = "", uuid_characteristic_write = "";
                                        byte[] data = new byte[0];
                                        int mtu = 20;

                                        BleManager.getInstance().notify(
                                                bleDevice,
                                                uuid_service,
                                                uuid_characteristic_notify,
                                                new BleNotifyCallback() {
                                                    @Override
                                                    public void onNotifySuccess() {
                                                        //打开通知操作成功
                                                    }

                                                    @Override
                                                    public void onNotifyFailure(BleException exception) {
                                                        //打开通知操作失败
                                                    }

                                                    @Override
                                                    public void onCharacteristicChanged(byte[] data) {
                                                        //打开通知后，设备发过来的数据将在这里出现
                                                    }
                                                });
                                        /**
                                         * 关闭notify
                                         */
                                        BleManager.getInstance().stopNotify(bleDevice, uuid_service, uuid_characteristic_notify);

                                        BleManager.getInstance().indicate(
                                                bleDevice,
                                                uuid_service,
                                                uuid_characteristic_indicate,
                                                new BleIndicateCallback() {
                                                    @Override
                                                    public void onIndicateSuccess() {
                                                        //打开通知操作成功
                                                    }

                                                    @Override
                                                    public void onIndicateFailure(BleException exception) {
                                                        //打开通知操作失败
                                                    }

                                                    @Override
                                                    public void onCharacteristicChanged(byte[] data) {
                                                        //打开通知后，设备发过来的数据将在这里出现
                                                    }
                                                }
                                        );
                                        /**
                                         * 关闭indicate
                                         */
                                        BleManager.getInstance().stopIndicate(bleDevice, uuid_service, uuid_characteristic_notify);

                                        /**
                                         * 读
                                         */
                                        BleManager.getInstance().read(bleDevice, uuid_service, uuid_characteristic_read, new BleReadCallback() {
                                            @Override
                                            public void onReadSuccess(byte[] data) {
                                                //读特征值数据成功
                                            }

                                            @Override
                                            public void onReadFailure(BleException exception) {
                                                //读特征值数据失败
                                            }
                                        });

                                        /**
                                         * 写
                                         */
                                        BleManager.getInstance().write(bleDevice, uuid_service, uuid_characteristic_write, data,new BleWriteCallback() {

                                                    @Override
                                                    public void onWriteSuccess(int current, int total, byte[] justWrite) {
                                                        //发送数据到设备成功（分包发送的情况下，可以通过方法中返回的参数查看发送进度）
                                                    }

                                                    @Override
                                                    public void onWriteFailure(BleException exception) {
                                                        //发送数据到设备失败
                                                    }
                                                });

                                        /**
                                         * 进行BLE数据相互发送的时候，一次最多能发送20个字节。如果需要发送的数据超过20个字节，有两种方法，
                                         * 一种是主动尝试拓宽MTU，另一种是采用分包传输的方式。框架中的write方法，当遇到数据超过20字节的情况时，
                                         * 默认是进行分包发送的
                                         */

                                        /**
                                         * 设置最大传输单元MTU
                                         */
                                        BleManager.getInstance().setMtu(bleDevice, mtu, new BleMtuChangedCallback() {
                                            @Override
                                            public void onSetMTUFailure(BleException exception) {
                                                //设置MTU失败
                                            }

                                            @Override
                                            public void onMtuChanged(int mtu) {
                                                //设置MTU成功，并获得当前设备传输支持的MTU值
                                            }
                                        });

                                        /**
                                         * 获取设备的实时信号强度Rssi
                                         */
                                        BleManager.getInstance().readRssi(bleDevice, new BleRssiCallback() {
                                            @Override
                                            public void onRssiFailure(BleException exception) {
                                                //读取设备的信号强度失败
                                            }

                                            @Override
                                            public void onRssiSuccess(int rssi) {
                                                //读取设备的信号强度成功
                                            }
                                        });

                                        /**
                                         * 几点经验分享：
                                         * 1，两次操作之间最好间隔一小段时间，如100ms,例如，onConnectSuccess之后，延迟100ms在进行notify,之后
                                         * 再延迟100ms进行write
                                         * 2.连接及连接后的过程中，时刻关注onDisConnected方法，然后做处理
                                         * 3.断开后如果需要重连也请延迟一段时间，否则会造成阻塞
                                         */
                                    }

                                    @Override
                                    public void onDisConnected(boolean isActiveDisConnected, BleDevice device, BluetoothGatt gatt, int status) {
                                        //断开连接，特指连接上并断开连接
                                    }
                                });
                            }
                        });
                    } else {
                        //蓝牙没打开
                        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                        startActivityForResult(intent, 0x01);
                    }
                } else {
                    //不支持BLE
                    Toast.makeText(MainActivity.this, "该设备不支持蓝牙BLE", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    private void permission() {
        requestRunPermisssion(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, new PermissionListener() {
            @Override
            public void onGranted() {
                //表示所有权限都授权了
//                Toast.makeText(MainActivity.this, "所有权限都授权了，可以搞事情了", Toast.LENGTH_SHORT).show();
                //我们可以执行打电话的逻辑
            }

            @Override
            public void onDenied(List<String> deniedPermission) {
                for (String permission : deniedPermission) {
                    Toast.makeText(MainActivity.this, "被拒绝的权限：" + permission, Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}
